﻿using System;
using System.Windows;
using System.Windows.Controls;
using ZuesControls.Commons;
using ZuesControls.Helpers;
using ZuesControls.Interfaces;


namespace ZuesControls.Controls
{
    public class ZSDialog : ContentControl, ILoading, IMessage,IProgressBarLoading
    {
        private ZSLoading PART_Loading;
        private ZSMessage PART_Message;
        private Border PART_ProgressBarBorder;
        private ZSProgressBar zsProgressBar;
        static ZSDialog()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ZSDialog), new FrameworkPropertyMetadata(typeof(ZSDialog)));
        }



        public double ProgressBarValueProperty
        {
            get { return (double)GetValue(ProgressBarValuePropertyProperty); }
            set { SetValue(ProgressBarValuePropertyProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ProgressBarValueProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ProgressBarValuePropertyProperty =
            DependencyProperty.Register("ProgressBarValueProperty", typeof(double), typeof(ZSDialog), new PropertyMetadata(0.00));



      



        public Task<OperateResult<T>> InvokeAsync<T>(Func<CancellationToken, Task<OperateResult<T>>> func, CancellationToken cancellationToken = default)
        {
            return this.Loading.InvokeAsync(func, cancellationToken);
        }

        public Task<OperateResult> InvokeAsync(Func<CancellationToken, Task<OperateResult>> func, CancellationToken cancellation = default)
        {
            return this.Loading.InvokeAsync(func, cancellation);
        }

        public void SetProgressBarValue(double value)
        {
            //if (PART_ProgressBarBorder.Visibility == Visibility.Collapsed)
            //{
            //    this.PART_ProgressBarBorder.Visibility = Visibility.Visible;
            //}
            this.Dispatcher.Invoke(() =>
            {
                this.ProgressBarValueProperty = value;
            });
         
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            this.PART_Loading = this.GetTemplateChild(nameof(this.PART_Loading)) as ZSLoading;
            this.PART_Message = this.GetTemplateChild(nameof(this.PART_Message)) as ZSMessage;
            this.PART_ProgressBarBorder = this.GetTemplateChild(nameof(PART_ProgressBarBorder)) as Border;
            ZSCard card = VisualHelper.FindChild<ZSCard>(PART_ProgressBarBorder) as ZSCard;
            Grid grid = card.Content as Grid;
            if (grid != null)
            {
                zsProgressBar = VisualHelper.FindChild<ZSProgressBar>(grid) as ZSProgressBar;
                zsProgressBar.ProgressBarEvent += ZsProgressBar_ProgressBarEvent;
            }
        }

        private  void ZsProgressBar_ProgressBarEvent(object? sender, ProgressBarEventArgs e)
        {
            this.PART_ProgressBarBorder.Visibility = Visibility.Collapsed;


        }

        private void PART_CloseButton_Click(object sender, RoutedEventArgs e)
        {
            this.PART_ProgressBarBorder.Visibility = Visibility.Collapsed;
            this.ProgressBarValueProperty = default;
        }

        public void HideLoading()
        {
            this.PART_Loading.HideLoading();
        }

        public void ShowLoading()
        {
            this.PART_Loading?.ShowLoading();
        }

        public void HandleBtnClickEvent()
        {
            this.MessageBox.HandleBtnClickEvent();
        }

        public void MessageBoxDisplay(Window window)
        {
            this.MessageBox.MessageBoxDisplay(window);
        }

        public void MessageBoxClose()
        {
            this.MessageBox.MessageBoxClose();
        }

        public async Task<MessageBoxResult> ShowMessageAsync(Window window, string messageBoxText = null, string caption = null, MessageBoxButton button = MessageBoxButton.OK, MessageBoxImage icon = MessageBoxImage.None, MessageBoxResult defaultResult = MessageBoxResult.None, MessageBoxOptions options = MessageBoxOptions.None)
        {
            return await this.MessageBox.ShowMessageAsync(window, messageBoxText, caption, button, icon, defaultResult, options);
        }

        public Task<MessageBoxResult> ShowMessageAsync(string messageBoxText)
        {
            throw new NotImplementedException();
        }

        public Task<MessageBoxResult> ShowMessageAsync(string messageBoxText, string caption)
        {
            throw new NotImplementedException();
        }

        public Task<MessageBoxResult> ShowMessageAsync(string messageBoxText, string caption, MessageBoxButton button)
        {
            throw new NotImplementedException();
        }

        public Task<MessageBoxResult> ShowMessageAsync(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
        {
            throw new NotImplementedException();
        }

        public Task<MessageBoxResult> ShowMessageAsync(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
        {
            throw new NotImplementedException();
        }

        public Task<MessageBoxResult> ShowMessageAsync(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options)
        {
            throw new NotImplementedException();
        }

        public async Task<MessageBoxResult> ShowMessageAsync(Window window, string messageBoxText)
        {
            return await this.MessageBox.ShowMessageAsync(window, messageBoxText);
        }

        public Task<MessageBoxResult> ShowMessageAsync(Window window, string messageBoxText, string caption)
        {
            throw new NotImplementedException();
        }

        public Task<MessageBoxResult> ShowMessageAsync(Window window, string messageBoxText, string caption, MessageBoxButton button)
        {
            throw new NotImplementedException();
        }

        public Task<MessageBoxResult> ShowMessageAsync(Window window, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
        {
            throw new NotImplementedException();
        }

        public Task<MessageBoxResult> ShowMessageAsync(Window window, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
        {
            throw new NotImplementedException();
        }

        public async Task<OperateResult> ShowProgressBarLoadingAsync(Func<CancellationToken, Task<OperateResult>> func, CancellationToken cancellationToken = default)
        {
            this.Dispatcher.Invoke(() =>
            {
                if (PART_ProgressBarBorder.Visibility == Visibility.Collapsed)
                {
                    this.PART_ProgressBarBorder.Visibility = Visibility.Visible;
                }

            });
            return await await Task.Factory.StartNew(async () =>
            {
                try
                {
                    return await func?.Invoke(cancellationToken);
                }
                catch (Exception ex)
                {
                    return OperateResult.CreateFailResult(ex.Message);
                }
                finally
                {
                    this.Dispatcher.Invoke(() =>
                    {
                        if (PART_ProgressBarBorder.Visibility == Visibility.Visible)
                        {
                            this.PART_ProgressBarBorder.Visibility = Visibility.Collapsed;
                        }

                    });
                }
            }, cancellationToken);
        }

        public Task<OperateResult<T>> ShowProgressBarLoadingAsync<T>(Func<CancellationToken, Task<OperateResult<T>>> func, CancellationToken cancellation = default)
        {
            throw new NotImplementedException();
        }

        public ILoading Loading
        {
            get
            {
                return this.PART_Loading;
            }
        }
        public IMessage MessageBox
        {
            get
            {
                return this.PART_Message;
            }
        }

    }
}
